package com.ruizhong.centercontroll.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruizhong.centercontroll.dao.TWebPageMapper;
import com.ruizhong.centercontroll.entity.TCommand;
import com.ruizhong.centercontroll.entity.TWebPage;
import com.ruizhong.centercontroll.service.TCommandService;
import com.ruizhong.centercontroll.service.TWebPageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class TWebPageServiceImpl extends ServiceImpl<TWebPageMapper,TWebPage> implements TWebPageService {

    @Autowired
    private TCommandService tCommandService;

    @Override
    @Transactional
    public void saveNewWebPageList(List<Map<String, Object>> webPageList, Integer pageId, boolean isNew) {
        final HashMap<Integer, List<Map<String, Object>>> webPageIdMapInitCommandList = new HashMap<>();
        deleteWebPagesByPageId(pageId);
        webPageList.stream().forEach(webPageOB -> {
            TWebPage tWebPage = new TWebPage();
            tWebPage.setPageId(pageId);
            tWebPage.setW(Double.parseDouble(webPageOB.get("w").toString()));
            tWebPage.setH(Double.parseDouble(webPageOB.get("h").toString()));
            tWebPage.setX(webPageOB.get("x") == null?0:Double.parseDouble(webPageOB.get("x").toString()));
            tWebPage.setY(webPageOB.get("y") == null?0:Double.parseDouble(webPageOB.get("y").toString()));
            tWebPage.setZ(Integer.parseInt(webPageOB.get("z").toString()));
            Object displayVariableName = webPageOB.get("displayVariableName");
            Object displayVariableValue = webPageOB.get("displayVariableValue");
            tWebPage.setDisplayVariableName(displayVariableName == null ? null : displayVariableName.toString());
            tWebPage.setDisplayVariableValue(displayVariableValue == null ? null : displayVariableValue.toString());
            Object conditionShow = webPageOB.get("conditionShow");
            tWebPage.setConditionShowData(conditionShow == null ? null : (Boolean) conditionShow ? 1 : 0);
            Object webPageUrlVariable = webPageOB.get("webPageUrlVariable");
            tWebPage.setWebPageUrlVariable(webPageUrlVariable == null ? null : webPageUrlVariable.toString());
            List<Map<String,Object>> initCommandList = null;
            Map logicGraph = (Map) webPageOB.get("logicGraph");
            if (!isNew){
                initCommandList = (List<Map<String, Object>>) webPageOB.get("initCommandList");
            }else{
                ObjectMapper mapper = new ObjectMapper();
                try {
                    String logicGraphString = mapper.writeValueAsString(logicGraph);
                    tWebPage.setLogicGraphData(logicGraphString);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
                Map<String, List> typeMapCommandList = TCommandServiceImpl.getCommandsByGraph(logicGraph);
                initCommandList = typeMapCommandList.get("initCommandList");
            }
            save(tWebPage);
            webPageIdMapInitCommandList.put(tWebPage.getId(), initCommandList);
        });
        Runnable runnable = new Runnable() {
            public void run() {
                tCommandService.saveCommandList("WEBPAGE", "init", webPageIdMapInitCommandList);
            }
        };
        new Thread(runnable).start();
    }

    @Override
    public List<TWebPage> getWebPagesByPageId(Integer pageId, Double pageWidth, Double pageHeight, Double aimPageWidth, Double aimPageHeight, Boolean display) throws JsonProcessingException {
        List<TWebPage> webPages = lambdaQuery()
                .eq(TWebPage::getPageId, pageId)
                .list();
        for (TWebPage webPage : webPages) {
            if (aimPageHeight != -1 && aimPageWidth != -1) {
                webPage.setW(Math.floor((webPage.getW() * aimPageWidth) / pageWidth));
                webPage.setH(Math.floor((webPage.getH() * aimPageHeight) / pageHeight));
                webPage.setX(Math.floor((webPage.getX() * aimPageWidth) / pageWidth));
                webPage.setY(Math.floor((webPage.getY() * aimPageHeight) / pageHeight));
            }
            webPage.setConditionShow(webPage.getConditionShowData() == null ? false : webPage.getConditionShowData() == 1);
            if (!display){
                String logicGraphData = webPage.getLogicGraphData();
                if (!StringUtils.isEmpty(logicGraphData)){
                    ObjectMapper mapper = new ObjectMapper();
                    Map map = mapper.readValue(logicGraphData, Map.class);
                    webPage.setLogicGraph(map);
                }
                List<TCommand> initCommands = tCommandService.getCommandListByMain(webPage.getId(), webPage.getType(), "init");
                initCommands = tCommandService.fillTCommands(initCommands);
                webPage.setInitCommandList(initCommands);
            }
        }
        return webPages;
    }

    @Override
    public List<TWebPage> getWebPageIdsByPageId(Integer pageId) {
        List<TWebPage> list = lambdaQuery()
                .select(TWebPage::getId)
                .eq(TWebPage::getPageId, pageId)
                .list();
        return list;
    }

    private void deleteWebPagesByPageId(Integer pageId) {
        QueryWrapper<TWebPage> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.lambda().eq(TWebPage::getPageId, pageId);
        remove(deleteWrapper);
    }
}
